#include <DataStruct.h>
#include <QDebug>
#include <cmath>
#include <ctime>
#include <algorithm>
#include <cstdlib>
#include <windows.h>

#define random(x) rand() % (x);
#define PI 3.1415926
#define Danger 50

//pve_DIS[i][j]: 球i,j的距离
//飞机的位置定在35号
double pve_DIS[36][36];
double pve_v2[36];
//U[i]: i号球的聚集度
int U[36];
double pve_px, pve_py;

/*
 * 计算向量模长
 * 参数x, y分别为向量横纵坐标
*/
double pve_Mod(double x, double y) {
    return sqrt(x * x + y * y);
}

/*
 * 将飞机的坐标系转化为qt的坐标系
 * 飞机相对正上方的偏转角（左偏为正）
*/
double angleConvert(double angle) {
    return -angle - 90;
}


/*
 * 获取战场信息及初始化
 * 参数: data: 战场数据
*/
void pve_init(DataStruct *data, KeyStruct *key) {
    key->forward = false;
    key->rotate_left = false;
    key->rotate_right = false;
    key->shoot = true;
    key->shield = false;
    if (data->plane1.angle < -180)
        data->plane1.angle += 360;
    else if (data->plane1.angle > 180)
        data->plane1.angle -= 360;

    pve_px = cos(angleConvert(data->plane1.angle) * PI / 180),
    pve_py = sin(angleConvert(data->plane1.angle) * PI / 180);

    for (int i = 0; i < data->ball_size; ++i) {
        pve_v2[i] = data->ball[i].v_x * data->ball[i].v_x + data->ball[i].v_y * data->ball[i].v_y;
        pve_DIS[i][35] =  pve_Mod(data->ball[i].x - data->plane1.x, data->ball[i].y - data->plane1.y);
        pve_DIS[35][i] = pve_DIS[i][35];
        for (int j = i + 1; j < data->ball_size; ++j) {
            pve_DIS[i][j] = pve_Mod(data->ball[i].x - data->ball[j].x, data->ball[i].y - data->ball[j].y);
            pve_DIS[j][i] = pve_DIS[i][j];
            if (pve_DIS[i][j] <= 200)
                U[i]++;
        }
    }
}


/*
 * 预测求位置，判断是否需要开盾
 * 参数: data: 战场数据
*/

bool pve_shield(DataStruct *data) {
    double min_dis = 3000.0;
    int min_index = 0;
    for (int i = 0; i < data -> ball_size; ++i) {
        double ball_x = data->ball[i].x + data->ball[i].v_x * 0.01;
        double ball_y = data->ball[i].y + data->ball[i].v_y * 0.01;
        //if (i == data->ball_size - 1)
            //qDebug() << data->ball[i].x << ' ' << data->ball[i].v_x << endl;
        double dis = pve_Mod(ball_x - data->plane1.x, ball_y - data->plane1.y);
        if (dis < min_dis) {
            min_dis = dis;
            min_index = i;
        }
    }
    if (min_dis <= data->plane1.r + data->ball[min_index].r + 10)
        return true;
    return  false;
}


bool pve_nice(DataStruct *data, BallStruct &ball, KeyStruct *key) {
    double pbx = ball.x - data->plane1.x, pby = ball.y - data->plane1.y;
    double pbx2 = ball.x + ball.v_x * 0.2 - data->plane1.x, pby2 = ball.y + ball.v_y * 0.2- data->plane1.y;
    double cross = pve_px * pby - pve_py * pbx;
    double sinB = fabs(cross) / pve_Mod(pve_px, pve_py) / pve_Mod(pbx, pby);
    double sinB2 = fabs(cross) / pve_Mod(pve_px, pve_py) / pve_Mod(pbx2, pby2);
    //qDebug() << sinB << sinB2;
    //qDebug() << sinB;
    if (sinB <= sin(0.02 * PI) && fabs(sinB - sinB2) <= 0.1)
        return true;
    else
        return false;
}

void pve_aim_ball(DataStruct *data, BallStruct &ball, KeyStruct *key) {

    //qDebug() << "飞机坐标为" << data->plane1.x << data->plane1.y << endl << "球坐标为" << ball.x << ball.y << endl;
    double ball_to_x = ball.v_x * 0.3 + ball.x,
           ball_to_y = ball.v_y * 0.3 + ball.y;

    double pbx = ball_to_x - data->plane1.x,
           pby = ball_to_y - data->plane1.y;
    if (ball_to_x <= ball.r) pbx += 2 * ball.r - 2 * ball_to_x;
    if (ball_to_y <= ball.r) pby += 2 * ball.r - 2 * ball_to_y;
    if (ball_to_x >= 2000 - ball.r) pbx += -2 * ball.r + 4000 - 2 * ball_to_x;
    if (ball_to_y >= 1500 - ball.r) pby += -2 * ball.r + 3000 - 2 * ball_to_y;
    //double t = 0.3 + pve_Mod(bx - data->plane1.x, by - data->plane1.y) / 1500;
    //double pbx
    double cross = pve_px * pby - pve_py * pbx;
    if (cross < 0) {
        key->rotate_left = true;
        key->rotate_right = false;
    }
    else {
        key->rotate_left = false;
        key->rotate_right = true;
    }
}

int pve_best(DataStruct *data, KeyStruct *key) {
    int best_id = -1;
    //先打近的（针对撞到飞机上的）
    int min_id = -1;
    double min_dis = 3000;
    for (int i = 0; i < data->ball_size; ++i) {
        /*double pve_DIS = pve_Mod(data->plane1.x - (data->ball[i].x + 0.2 * data->ball[i].v_x), data->plane1.y - (data->ball[i].y + 0.2 * data->ball[i].v_y));
        if (pve_DIS[i][35] < min_pve_DIS) {
            min_pve_DIS = pve_DIS[i][35];
            min_id = i;
        }
        if (pve_DIS <= 5 * Danger)
            best_id = i;*/
        if (pve_DIS[i][35] < min_dis) {
            min_dis = pve_DIS[i][35];
            min_id = i;
        }
    }
    qDebug() << min_id << ' ' << min_dis;
    //qDebug() << min_pve_DIS;
    if (min_dis <= 7 * Danger)
        best_id = min_id;
    if (best_id != -1)
        return best_id;

    //再打靠近飞机的
    for (int i = 0; i < data->ball_size; ++i) {
        double pbx = data->plane1.x - data->ball[i].x,
               pby = data->plane1.y - data->ball[i].y;
        double ball_v_x = data->ball[i].v_x,
               ball_v_y = data->ball[i].v_y;
        double cross = pbx * ball_v_y - pby * ball_v_x;
        double theta = asin(cross / pve_Mod(pbx, pby) / pve_Mod(ball_v_x, ball_v_y));   //球的速度与球飞机向量夹角

        double angle_corner = asin((data->plane1.r + data->ball[i].r) / pve_DIS[i][35]);    //边界角度
        if (theta <= angle_corner) {
            if (best_id == -1)  //还没有候选球
                best_id = i;
            else if (pve_v2[i] < pve_v2[best_id])   //再比较速度（先试试效果）
                best_id = i;
        }
    }
    if (best_id != -1)  //找到了！
        return best_id;

    //重新挑选目标
    best_id = 0;    //先挑一个
    for (int i = 0; i < data->ball_size; ++i) {
        //qDebug() << pve_v2[i];
        if (pve_nice(data, data->ball[i], key) == false)
            continue;
        if (pve_v2[i] <= 170000) {
            best_id = i;
        }
        double dis = pve_DIS[35][i];
        double dis_shoot_id = pve_DIS[35][best_id];
        if (dis * 10 + data->ball[i].hp * 1000 + U[i] * 100 < dis_shoot_id * 10 + data->ball[best_id].hp * 1000 + U[best_id] * 100)
            best_id = i;
    }
    return best_id;
}

/*
 * 控制飞机行动
 * 参数: data: 战场数据, key: 飞机动作
*/
void ai_pve(DataStruct *data, KeyStruct *key) {
    static int time = 0;
    time++;
    //qDebug() << data->plane1.angle;
    //初始化飞机参数
    pve_init(data, key);

    //判断是否要开盾
    if (pve_shield(data))
        key->shield = true;

    //如果球个数不为零
    /*static int last_id = 0;*/

    if (data->ball_size)
    {
        int shoot_id = pve_best(data, key);
        //瞄准优先级最高目标
        pve_aim_ball(data, data->ball[shoot_id], key);
    }
}
